package com.cryptoneedle.garden.service.garden.ods;


import com.cryptoneedle.garden.constant.DorisConstant;
import com.cryptoneedle.garden.dto.DwdColumnCreateDto;
import com.cryptoneedle.garden.entity.garden.mapping.MappingColumn;
import com.cryptoneedle.garden.entity.garden.mapping.MappingJoin;
import com.cryptoneedle.garden.entity.garden.mapping.MappingTable;
import com.cryptoneedle.garden.entity.garden.ods.OdsColumn;
import com.cryptoneedle.garden.entity.garden.ods.OdsColumnTranslate;
import com.cryptoneedle.garden.entity.garden.ods.OdsTable;
import com.cryptoneedle.garden.enums.JoinType;
import com.cryptoneedle.garden.enums.MappingFieldType;
import com.cryptoneedle.garden.enums.OdsTranslateType;
import com.cryptoneedle.garden.service.crud.garden.doris.*;
import com.cryptoneedle.garden.service.util.ConfigUtil;
import com.cryptoneedle.garden.vo.JoinTableConfigVo;
import com.cryptoneedle.garden.vo.OdsColumnTranslateVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>description:  </p>
 *
 * @author CryptoNeedle
 * @date 2025-09-26
 */
@Service
@Slf4j
@Transactional
public class OdsService {

    @Resource
    private OdsService odsService;

    @Autowired
    private AddDorisService add;
    @Autowired
    private DeleteDorisService delete;
    @Autowired
    private FoundDorisService select;
    @Autowired
    private PatchDorisService patch;
    @Autowired
    private SaveDorisService save;

    @Resource
    private ConfigUtil configUtil;

    public void mappingTableConfig(JoinTableConfigVo vo) {
        String ods = configUtil.ods();
        String primaryCatalogName = vo.getPrimaryCatalogName();
        if (!StringUtils.equals(primaryCatalogName, DorisConstant.DEFAULT_CATALOG)) {
            throw new RuntimeException("限制主目录为" + DorisConstant.DEFAULT_CATALOG);
        }
        String primaryDatabaseName = vo.getPrimaryDatabaseName();
        if (!StringUtils.equals(primaryDatabaseName, ods)) {
            throw new RuntimeException("限制主库为" + ods);
        }

        String primaryTableName = vo.getPrimaryTableName();
        OdsTable odsTable = select.odsTable(primaryCatalogName, primaryDatabaseName, primaryTableName);
        if (odsTable == null) {
            throw new RuntimeException("主表不存在");
        }

        String mapping = configUtil.mapping();
        List<JoinTableConfigVo.JoinTableConfigs> joinTableConfigs = vo.getJoinTableConfigs();
        if (joinTableConfigs.isEmpty()) {
            throw new RuntimeException("关联表配置不能为空");
        }

        for (JoinTableConfigVo.JoinTableConfigs joinTableConfig : joinTableConfigs) {
            String joinCatalogName = joinTableConfig.getJoinCatalogName();
            if (!StringUtils.equals(joinCatalogName, DorisConstant.DEFAULT_CATALOG)) {
                throw new RuntimeException("限制关联目录为" + DorisConstant.DEFAULT_CATALOG);
            }

            String joinDatabaseName = joinTableConfig.getJoinDatabaseName();
            if (!StringUtils.equals(joinDatabaseName, mapping)) {
                throw new RuntimeException("限制关联库为" + mapping);
            }

            String joinTableName = joinTableConfig.getJoinTableName();
            MappingTable mappingTable = select.mappingTable(joinCatalogName, joinDatabaseName, joinTableName);
            if (mappingTable == null) {
                throw new RuntimeException("关联表不存在");
            }

            // 设定：一张ODS表只生成一张与Mapping相关的表，故此请求每次都要覆盖之前的配置
            // 删除之前配置的内容
            List<MappingJoin> mappingJoins = select.mappingJoins(primaryCatalogName, primaryDatabaseName, primaryTableName);
            delete.mappingJoins(mappingJoins);

            JoinType joinType = joinTableConfig.getJoinType();
            List<JoinTableConfigVo.JoinTableConfigs.JoinColumnConfig> joinColumnConfigs = joinTableConfig.getJoinColumnConfigs();
            if (JoinType.CROSS_JOIN.equals(joinType) || joinColumnConfigs.isEmpty()) {
                throw new RuntimeException("关联列配置不能为空");
            }
            for (JoinTableConfigVo.JoinTableConfigs.JoinColumnConfig joinColumnConfig : joinColumnConfigs) {
                String primaryColumnName = joinColumnConfig.getPrimaryColumnName();
                OdsColumn odsColumn = select.odsColumn(primaryCatalogName, primaryDatabaseName, primaryTableName, primaryColumnName);
                if (odsColumn == null) {
                    throw new RuntimeException("主表列不存在");
                }

                String joinColumnName = joinColumnConfig.getJoinColumnName();
                MappingColumn mappingColumn = select.mappingColumn(joinCatalogName, joinDatabaseName, joinTableName, joinColumnName);
                if (mappingColumn == null) {
                    throw new RuntimeException("关联表列不存在");
                }
                if (MappingFieldType.MAPPING_CODE.equals(mappingColumn.getMappingFieldType())) {
                    throw new RuntimeException("关联表列映射类型只允许为 MAPPING_CODE");
                }

                // 创建关联信息
                MappingJoin mappingJoin = new MappingJoin()
                        .setPrimaryCatalogName(primaryCatalogName)
                        .setPrimaryDatabaseName(primaryDatabaseName)
                        .setPrimaryTableName(primaryTableName)
                        .setPrimaryColumnName(primaryColumnName)
                        .setJoinType(joinType)
                        .setJoinCatalogName(joinCatalogName)
                        .setJoinDatabaseName(joinDatabaseName)
                        .setJoinTableName(joinTableName)
                        .setJoinColumnName(joinColumnName);
                save.save(mappingJoin);
            }
        }
    }

    public void convertTableConfig(OdsColumnTranslateVo vo) {
        String ods = configUtil.ods();
        String catalogName = vo.getCatalogName();
        if (!StringUtils.equals(catalogName, DorisConstant.DEFAULT_CATALOG)) {
            throw new RuntimeException("限制目录为" + DorisConstant.DEFAULT_CATALOG);
        }
        String databaseName = vo.getDatabaseName();
        if (!StringUtils.equals(databaseName, ods)) {
            throw new RuntimeException("限制库为" + ods);
        }

        String tableName = vo.getTableName();
        OdsTable odsTable = select.odsTable(catalogName, databaseName, tableName);
        if (odsTable == null) {
            throw new RuntimeException("表不存在");
        }

        // 删除之前配置的数据
        List<OdsColumnTranslate> odsColumnTranslates = select.odsColumnTranslates(catalogName, databaseName, tableName, catalogName);
        delete.odsColumnTranslates(odsColumnTranslates);

        // 创建转换信息
        List<OdsColumnTranslateVo.TranslateConfig> translateConfigs = vo.getTranslateConfigs();
        if (translateConfigs.size() > 30) {
            throw new RuntimeException("限制翻译值数量应小于30个");
        }

        AtomicInteger atomicInteger = new AtomicInteger(1);
        odsColumnTranslates = translateConfigs.stream()
                .map(translateConfig ->
                        new OdsColumnTranslate()
                                .setCatalogName(catalogName)
                                .setDatabaseName(databaseName)
                                .setTableName(tableName)
                                .setColumnName(catalogName)
                                .setTranslateType(translateConfig.getTranslateType())
                                .setDataValue(translateConfig.getDataValue())
                                .setTranslateValue(translateConfig.getTranslateValue())
                                .setSequence(atomicInteger.getAndIncrement()))
                .toList();
        save.odsColumnTranslates(odsColumnTranslates);

        // 检查 ELSE 类型的配置最多只有一个
        List<OdsColumnTranslateVo.TranslateConfig> elseConfigs = translateConfigs.stream()
                .filter(config -> OdsTranslateType.ELSE.equals(config.getTranslateType()))
                .toList();
        if (elseConfigs.size() > 1) {
            throw new RuntimeException("ELSE类型的翻译配置最多只能有一个，当前有：" + elseConfigs.size() + "个");
        }
        if (elseConfigs.isEmpty()) {
            OdsColumnTranslate elseTranslate = new OdsColumnTranslate()
                    .setCatalogName(catalogName)
                    .setDatabaseName(databaseName)
                    .setTableName(tableName)
                    .setColumnName(catalogName)
                    .setTranslateType(OdsTranslateType.ELSE)
                    .setDataValue(null)
                    .setTranslateValue(null)
                    .setSequence(atomicInteger.getAndIncrement());
            save.save(elseTranslate);
        }
    }

    public void createDwd(String tableName) {
        String ods = configUtil.ods();
        String mapping = configUtil.mapping();
        OdsTable odsTable = select.odsTable(DorisConstant.DEFAULT_CATALOG, ods, tableName);
        if (odsTable == null) {
            throw new RuntimeException("表不存在");
        }

        List<OdsColumn> odsColumns = select.odsColumns();
        List<OdsColumn> uniOdsColumns = odsColumns.stream().filter(column -> "UNI".equals(column.getColumnKey())).toList();
        List<OdsColumn> commonOdsColumns = odsColumns.stream().filter(column -> !"UNI".equals(column.getColumnKey())).toList();

        List<OdsColumnTranslate> odsColumnTranslates = select.odsColumnTranslates(DorisConstant.DEFAULT_CATALOG, ods, tableName);
        Map<String, List<OdsColumnTranslate>> odsColumnTranslateMap = odsColumnTranslates.stream()
                .collect(Collectors.groupingBy(OdsColumnTranslate::getColumnName));

        List<MappingJoin> mappingJoins = select.mappingJoins(DorisConstant.DEFAULT_CATALOG, ods, tableName);
        List<String> joinTableNames = mappingJoins.stream().map(MappingJoin::getJoinTableName).distinct().toList();
        HashMap<String, List<MappingColumn>> mappingTableMap = new HashMap<>();
        List<MappingColumn> mappingColumns = new ArrayList<>();
        for (String joinTableName : joinTableNames) {
            List<MappingColumn> columns = select.mappingColumns(DorisConstant.DEFAULT_CATALOG, mapping, joinTableName);
            mappingTableMap.put(joinTableName, columns);
            mappingColumns.addAll(columns);
        }

        List<DwdColumnCreateDto> dtos = new ArrayList<>();

        // 先处理 uniOdsColumns
        for (OdsColumn uniOdsColumn : uniOdsColumns) {
//            boolean changeColumnName =
//
//            String dwdColumnName;
//
//            dtos.add(new DwdColumnCreateDto()
//                    .setDwdColumnName(dwdColumnName)
//                    .setOgriginColumnTable(uniOdsColumn.getTableName())
//                    .setOgriginColumnName(uniOdsColumn.getColumnName()));
        }
        // 处理 commonOdsColumns
    }
}